package xin.shaozeming.base.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import xin.shaozeming.base.common.Enum.base.LoggerType;
import xin.shaozeming.base.common.Enum.base.State;
import xin.shaozeming.base.common.aop.annotation.ParamsDecrypted;
import xin.shaozeming.base.common.aop.annotation.Permission;
import xin.shaozeming.base.common.aop.annotation.SysLogger;
import xin.shaozeming.base.common.aop.annotation.TokenCheck;
import xin.shaozeming.base.common.utils.ParamUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: 邵泽铭
 * @date: 2019/3/30
 * @description:
 **/
@Log4j2
public class BaseController<M extends IService<T>, T> {
    @Autowired
    private M iService;


    @SysLogger(name = "查询列表",type = LoggerType.SELECT)
    @TokenCheck
    @ParamsDecrypted
    @ApiOperation(value = "基础分页", notes = "基础分页", response = Response.class)
    @PostMapping("selectPage")
    public Response<IPage<T>> selectPage(HttpServletRequest request,
                                         @ApiParam(name = "page" ,value = "页码") String page ,
                                         @ApiParam(name = "size" ,value = "数量") String size,
                                         @ApiParam(name = "sortParam" ,value = "排序字段") String sortParam,
                                         @ApiParam(name = "direction" ,value = "排序",defaultValue = "0") String direction,
                                         @ApiParam(name = "param" ,value = "实体json") String param){
        Type type=((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        QueryWrapper<T> queryWrapper=ParamUtils.getParamWrapper(type.getTypeName(),param);
        Page<T> pageable=ParamUtils.getPage(page,size,sortParam,direction,true);
        return new Response<IPage<T>>(iService.page(pageable,queryWrapper) );
    }

    /*额外的分页操作*/
    public  void remainPage(String t){};

    private T getEnityParam(String param){
        Type type=((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        return ParamUtils.parseEnityParam(type.getTypeName(),param);
    }

    @SysLogger(name = "单个查询",type = LoggerType.SELECT)
    @Permission(code = "list")
    @TokenCheck
    @ParamsDecrypted
    @ApiOperation(value = "主键查询", notes = "主键查询", response = Response.class)
    @PostMapping("selectById")
    public Response selectById(HttpServletRequest request,
                               @ApiParam(name = "id", value = "id") String id) {
        return new Response<>(iService.getById(new Integer(id)));
    }

    @SysLogger(name = "单个删除",type = LoggerType.DELETE)
    @Permission(code = "delete")
    @TokenCheck
    @ParamsDecrypted
    @ApiOperation(value = "主键删除", notes = "主键删除", response = Response.class)
    @PostMapping("deleteById")
    public Response deleteById(HttpServletRequest request,
                               @ApiParam(name = "id", value = "id") String id) {
        if(iService.removeById(new Integer(id))){
            return new Response<>(State.RES_SUCCES.getCode());
        }
        return new Response<>(State.RES_ERROR.getCode());
    }

    @SysLogger(name = "批量删除",type = LoggerType.DELETE)
    @Permission(code = "delete")
    @TokenCheck
    @ParamsDecrypted
    @ApiOperation(value = "批量删除", notes = "批量删除", response = Response.class)
    @PostMapping("deleteByIds")
    public Response deleteByIds(HttpServletRequest request,
                                @ApiParam(name = "ids", value = "ids")String ids) {
        List<Integer> list=new ArrayList<>();

        String[] idList=  ids.split(",");
        for(String item:idList){
            list.add( new Integer(item));
        }
        if(iService.removeByIds(list)){
            return new Response<>(State.RES_SUCCES.getCode());
        }
        return new Response<>(State.RES_ERROR.getCode());
    }

    @SysLogger(name = "新增更新",type = LoggerType.SAVE,entity = 2)
    @Permission(code = "add,update")
    @TokenCheck
    @ParamsDecrypted
    @ApiOperation(value = "保存或更新", notes = "保存或更新", response = Response.class)
    @PostMapping("save")
    public Response save(HttpServletRequest request,
                        T t) {

        if(StringUtils.isEmpty(t)){
            return  new Response(State.RES_PARAMERROR.getCode());
        }
        decideSaveOrUpdate(t);
        remainSave(t);
        if (iService.saveOrUpdate(t)) {
            return new Response<>(State.RES_SUCCES.getCode());
        }
        return new Response<>(State.RES_ERROR.getCode());
    }





    /*处理保存或更新两种操作的差异*/
    private void decideSaveOrUpdate(T t) {
       ParamUtils.parseDecideSaveOrUpdate(t.getClass(),t);

    }



    /*额外的保存或更新操作*/
    public  void remainSave(T t){};

/*    @TokenCheck
    @Profile({"default","dev"})
    @ParamsDecrypted
    @ApiOperation(value = "查看实体参数", notes = "查看实体参数", response = Response.class)
    @RequestMapping(value = "PARAM",method = RequestMethod.HEAD)
    public Response PARAM(@ApiParam(name = "key", value = "key") String key,
                          @ApiParam(name = "token", value = "token") String token,
                          T t) {
        return new Response<>();
    }*/
}
